package com.java1234.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.java1234.entity.Operationlogs;
import com.java1234.entity.R;
import com.java1234.entity.SysMenu;
import com.java1234.service.OperationLogsService;
import com.java1234.service.SysMenuService;
import com.java1234.util.IpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 系统菜单Controller控制器
 */
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController {
    private static final Logger logger = LoggerFactory.getLogger(SysMenuController.class);

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private OperationLogsService operationLogService;

    @Autowired
    private HttpServletRequest request;

    /**
     * 获取当前登录用户的用户名
     * @return 用户名
     */
    private String getCurrentUsername() {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            return ((UserDetails) principal).getUsername();
        } else {
            return principal.toString();
        }
    }

    /**
     * 查询所有菜单树信息
     * @return
     */
    @GetMapping("/treeList")
    @PreAuthorize("hasAuthority('system:menu:query')")
    public R list() {
        long startTime = System.currentTimeMillis(); // 记录操作开始时间
        logger.info("查询所有菜单树信息");

        List<SysMenu> menuList = sysMenuService.list(new QueryWrapper<SysMenu>()
                .orderByAsc("order_num")); // 按照排序号升序排列

        long endTime = System.currentTimeMillis(); // 记录操作结束时间
        long elapsedTime = endTime - startTime; // 计算耗时

        // 记录操作日志
        Operationlogs log = new Operationlogs();
        log.setUsername(getCurrentUsername()); // 获取当前登录用户的用户名
        log.setOperation("查询所有菜单");
        log.setMethod("GET /sys/menu/treeList");
        log.setParams("");
        log.setResult("成功");
        log.setElapsedTime(elapsedTime);
        log.setCreateTime(new Date());
        log.setIpAddress(IpUtil.getIpAddr(request)); // 获取真实的客户端IP地址
        log.setStatus("OK");
        operationLogService.logOperation(log);

        return R.ok().put("treeMenu", sysMenuService.buildTreeMenu(menuList)); // 构建菜单树
    }

    /**
     * 添加或者修改
     * @param sysMenu
     * @return
     */
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:menu:add') || hasAuthority('system:menu:edit')")
    public R save(@RequestBody SysMenu sysMenu) {
        long startTime = System.currentTimeMillis(); // 记录操作开始时间
        if (sysMenu.getId() == null || sysMenu.getId() == -1) {
            logger.info("添加新菜单项: {}", sysMenu);
            sysMenu.setCreateTime(new Date());
            sysMenuService.save(sysMenu);

            // 记录操作日志
            Operationlogs log = new Operationlogs();
            log.setUsername(getCurrentUsername()); // 获取当前登录用户的用户名
            log.setOperation("添加菜单");
            log.setMethod("POST /sys/menu/save");
            log.setParams(sysMenu.toString());
            log.setResult("成功");
            log.setElapsedTime(System.currentTimeMillis() - startTime);
            log.setCreateTime(new Date());
            log.setIpAddress(IpUtil.getIpAddr(request)); // 获取真实的客户端IP地址
            log.setStatus("OK");
            operationLogService.logOperation(log);
        } else {
            logger.info("修改菜单项: {}", sysMenu);
            sysMenu.setUpdateTime(new Date());
            sysMenuService.updateById(sysMenu);

            // 记录操作日志
            Operationlogs log = new Operationlogs();
            log.setUsername(getCurrentUsername()); // 获取当前登录用户的用户名
            log.setOperation("修改菜单");
            log.setMethod("POST /sys/menu/save");
            log.setParams(sysMenu.toString());
            log.setResult("成功");
            log.setElapsedTime(System.currentTimeMillis() - startTime);
            log.setCreateTime(new Date());
            log.setIpAddress(IpUtil.getIpAddr(request)); // 获取真实的客户端IP地址
            log.setStatus("OK");
            operationLogService.logOperation(log);
        }
        return R.ok();
    }

    /**
     * 根据id查询
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('system:menu:query')")
    public R findById(@PathVariable(value = "id") Integer id) {
        long startTime = System.currentTimeMillis(); // 记录操作开始时间
        logger.info("根据ID查询菜单项: {}", id);
        SysMenu sysMenu = sysMenuService.getById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("sysMenu", sysMenu);

        long endTime = System.currentTimeMillis(); // 记录操作结束时间
        long elapsedTime = endTime - startTime; // 计算耗时

        // 记录操作日志
        Operationlogs log = new Operationlogs();
        log.setUsername(getCurrentUsername()); // 获取当前登录用户的用户名
        log.setOperation("查询菜单");
        log.setMethod("GET /sys/menu/{id}");
        log.setParams("ID: " + id);
        log.setResult("成功");
        log.setElapsedTime(elapsedTime);
        log.setCreateTime(new Date());
        log.setIpAddress(IpUtil.getIpAddr(request)); // 获取真实的客户端IP地址
        log.setStatus("OK");
        operationLogService.logOperation(log);

        return R.ok(map);
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @GetMapping("/delete/{id}")
    @PreAuthorize("hasAuthority('system:menu:delete')")
    public R delete(@PathVariable(value = "id") Long id) {
        long startTime = System.currentTimeMillis(); // 记录操作开始时间
        logger.info("删除菜单项: {}", id);
        // 查询与要删除的菜单ID相同的parent_id的子菜单数量。
        // 即当前节点如果作为父节点是否有子节点，有则计入
        int count = sysMenuService.count(new QueryWrapper<SysMenu>().eq("parent_id", id));
        if (count > 0) {
            logger.warn("菜单项 {} 下有子菜单，无法删除", id);

            // 记录操作日志
            Operationlogs log = new Operationlogs();
            log.setUsername(getCurrentUsername()); // 获取当前登录用户的用户名
            log.setOperation("删除菜单");
            log.setMethod("GET /sys/menu/delete/{id}");
            log.setParams("ID: " + id);
            log.setResult("失败: 子菜单存在");
            log.setElapsedTime(System.currentTimeMillis() - startTime);
            log.setCreateTime(new Date());
            log.setIpAddress(IpUtil.getIpAddr(request)); // 获取真实的客户端IP地址
            log.setStatus("FAIL");
            operationLogService.logOperation(log);

            return R.error("请先删除子菜单");
        }

        // 如果没有子菜单，继续删除
        sysMenuService.removeById(id);
        logger.info("成功删除菜单项: {}", id);

        long endTime = System.currentTimeMillis(); // 记录操作结束时间
        long elapsedTime = endTime - startTime; // 计算耗时

        // 记录操作日志
        Operationlogs log = new Operationlogs();
        log.setUsername(getCurrentUsername()); // 获取当前登录用户的用户名
        log.setOperation("删除菜单");
        log.setMethod("GET /sys/menu/delete/{id}");
        log.setParams("ID: " + id);
        log.setResult("成功");
        log.setElapsedTime(elapsedTime);
        log.setCreateTime(new Date());
        log.setIpAddress(IpUtil.getIpAddr(request)); // 获取真实的客户端IP地址
        log.setStatus("OK");
        operationLogService.logOperation(log);

        return R.ok();
    }
}